package com.wgchao.amc.service.impl;

import com.wgchao.amc.common.EvaluateInfo;
import com.wgchao.amc.common.ResultCommon;
import com.wgchao.amc.entity.autho.SysAuthoUser;
import com.wgchao.amc.entity.autho.SysAuthoUserFunc;
import com.wgchao.amc.entity.base.SysBaseFunc;
import com.wgchao.amc.entity.base.SysBaseMenu;
import com.wgchao.amc.entity.base.SysBaseUser;
import com.wgchao.amc.entity.menu.SysMenuProject;
import com.wgchao.amc.mapstruct.dto.SysAuthoUserDTO;
import com.wgchao.amc.mapstruct.dto.SysAuthoUserFuncDTO;
import com.wgchao.amc.mapstruct.mapper.SysAuthoUserFuncMapper;
import com.wgchao.amc.mapstruct.mapper.expand.SysAuthoUserMapperExpand;
import com.wgchao.amc.repository.autho.SysAuthoUserFuncRepository;
import com.wgchao.amc.repository.autho.SysAuthoUserRepository;
import com.wgchao.amc.repository.base.SysBaseFuncRepository;
import com.wgchao.amc.repository.base.SysBaseMenuRepository;
import com.wgchao.amc.repository.base.SysBaseUserRepository;
import com.wgchao.amc.repository.menu.SysMenuProjectRepository;
import com.wgchao.amc.service.EvaluateService;
import com.wgchao.amc.service.UserAuthoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @ClassName: UserAuthoServiceImpl
 * @author: wgchao
 * @createTime: 2019/10/31 10:55 AM
 * @Description: 用户权限管理
 */
@Service
@Transactional
public class UserAuthoServiceImpl implements UserAuthoService, EvaluateService {
    @Autowired
    private SysMenuProjectRepository projectRepository;
    @Autowired
    private SysBaseMenuRepository menuRepository;
    @Autowired
    private SysBaseFuncRepository funcRepository;
    @Autowired
    private SysBaseUserRepository userRepository;
    @Autowired
    private SysAuthoUserRepository authoUserRepository;
    @Autowired
    private SysAuthoUserMapperExpand authoUserMapperExpand;
    @Autowired
    private SysAuthoUserFuncRepository authoUserFuncRepository;
    @Autowired
    private SysAuthoUserFuncMapper authoUserFuncMapper;

    /**
     * 为用户分配菜单权限
     * @param userId 用户ID
     * @param proMark 项目标示
     * @param authoUserDTOS 菜单权限信息
     * @return
     * @throws Exception
     */
    @Override
    public ResultCommon<List<SysAuthoUserDTO>> assign(Long userId, String proMark, List<SysAuthoUserDTO> authoUserDTOS) throws Exception {
        //数据检校
        EvaluateInfo evaluateInfo = evaluate(authoUserDTOS, gads -> {
            List<SysAuthoUserDTO> gaDtos = (List<SysAuthoUserDTO>) gads;
            Optional<SysBaseUser> userOptional = userRepository.findById(userId);
            if(!userOptional.isPresent()){
                return new EvaluateInfo(false, "用户不存在");
            }
            SysBaseUser user = userOptional.get();
            if(user.isDel()){
                return new EvaluateInfo(false, "用户已删除");
            }
            if(user.isCancel()){
                return new EvaluateInfo(false, "用户已注销");
            }
            SysMenuProject project = projectRepository.findFirstByProMark(proMark);
            if(project == null){
                return new EvaluateInfo(false, "项目不存在");
            }
            for(SysAuthoUserDTO userDTO:gaDtos){
                Optional<SysBaseMenu> menuOptional = menuRepository.findById(userDTO.getMenuId());
                if(!menuOptional.isPresent()){
                    return new EvaluateInfo(false, userDTO.getMenuId()+"菜单不存在");
                }
                SysBaseMenu menu = menuOptional.get();
                if(!menu.getProMark().equals(proMark)){
                    return new EvaluateInfo(false, menu.getMenuName()+"菜单不再该项目中");
                }
                List<SysAuthoUserFuncDTO> userFuncs = userDTO.getFuncInfos();
                if(userFuncs!=null && !userFuncs.isEmpty() ){
                    for(SysAuthoUserFuncDTO funcDTO:userFuncs){
                        Optional<SysBaseFunc> funcOptional = funcRepository.findById(funcDTO.getFuncId());
                        if(!funcOptional.isPresent()){
                            return new EvaluateInfo(false, funcDTO.getFuncId()+"功能操作不存在");
                        }
                    }
                }
            }
            return new EvaluateInfo(true, null);
        });
        if(!evaluateInfo.isSuccess()){
            return ResultCommon.fail(evaluateInfo.getMsg());
        }

        //删除原有的菜单权限
        List<SysAuthoUser> oldGas = authoUserRepository.findAllByUserIdAndProMarkOrderById(userId, proMark);
        if(oldGas!=null && !oldGas.isEmpty()){
            for(SysAuthoUser oldGa:oldGas){
                List<SysAuthoUserFunc> gafuncs = authoUserFuncRepository.findAllByAuId(oldGa.getId());
                if(gafuncs!=null && !gafuncs.isEmpty()){
                    authoUserFuncRepository.deleteAll(gafuncs);
                }
            }
            authoUserRepository.deleteAll(oldGas);
        }

        //设置新的菜单权限信息
        for(SysAuthoUserDTO authoUserDTO:authoUserDTOS){
            SysAuthoUser authoUser = authoUserMapperExpand.toEntity(authoUserDTO);
            authoUser.setUserId(userId);
            authoUser.setProMark(proMark);
            authoUser.setCreateTime(new Date());
            authoUser = authoUserRepository.save(authoUser);

            List<SysAuthoUserFuncDTO> userFuncs = authoUserDTO.getFuncInfos();
            if(userFuncs!=null && !userFuncs.isEmpty() ){
                //保存菜单功能信息
                for(SysAuthoUserFuncDTO funcDTO:userFuncs){
                    SysAuthoUserFunc authoUserFunc = authoUserFuncMapper.toEntity(funcDTO);
                    authoUserFunc.setAuId(authoUser.getId());
                    authoUserFunc = authoUserFuncRepository.save(authoUserFunc);
                }
            }
        }

        List<SysAuthoUser> authoGroups = authoUserRepository.findAllByUserIdAndProMarkOrderById(userId, proMark);
        authoUserDTOS = authoGroups.stream().map(sysAuthoGroup -> {
            SysAuthoUserDTO authoUserDTO = authoUserMapperExpand.toDTO(sysAuthoGroup);
            authoUserDTO = authoUserMapperExpand.getFuncInfo(authoUserDTO);
            return authoUserDTO;
        }).collect(Collectors.toList());
        return ResultCommon.success().setData(authoUserDTOS);
    }

    /**
     * 查询用户菜单权限
     * @param userId 用户ID
     * @param proMark 项目标示
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(readOnly = true)
    public ResultCommon<List<SysAuthoUserDTO>> search(Long userId, String proMark) throws Exception {
        List<SysAuthoUser> authoGroups = authoUserRepository.findAllByUserIdAndProMarkOrderById(userId, proMark);
        List<SysAuthoUserDTO> authoUserDTOS = authoGroups.stream().map(sysAuthoGroup -> {
            SysAuthoUserDTO authoUserDTO = authoUserMapperExpand.toDTO(sysAuthoGroup);
            authoUserDTO = authoUserMapperExpand.getFuncInfo(authoUserDTO);
            return authoUserDTO;
        }).collect(Collectors.toList());
        return ResultCommon.success().setData(authoUserDTOS);
    }
}
